Skip to content

Add in-dive annotation messages#276

Merged
follesoe merged 4 commits into
masterfrom
jf/in-dive-annotations
Jun 30, 2026
Merged

Add in-dive annotation messages#276
follesoe merged 4 commits into
masterfrom
jf/in-dive-annotations

Conversation

@follesoe

@follesoe follesoe commented Jun 29, 2026

Copy link
Copy Markdown
Member

Summary

Adds the protocol for in-dive annotations: during a dive a diver (or any connected client) taps an annotation type in the app's command palette, and the annotation is broadcast to every connected client and recorded into the dive logfile. Part of the Blueye Cloud in-dive annotations feature.

Annotations are self-contained — each one carries the type's display fields (type_name, type_icon, type_color) inline, so the drone, connected clients, and the dive logfile can render it with no separate catalogue. The app keeps the full annotation-type catalogue locally (synced from Blueye Cloud) to drive its palette; only complete annotations go over the wire. type_slug is kept so Blueye Cloud can correlate the annotation back to its type on import.

Note: an earlier revision of this PR pushed/embedded an AnnotationCatalog to the drone. That was simplified away in favour of self-contained annotations (see commit history) — it removes the catalogue-sync messages and the "push catalogue before the dive" ordering dependency.

Messages

message_formats.proto

  • AnnotationSource enum — CLOUD / APP / DRONE.
  • Annotation — a self-contained annotation: type_slug, type_name, type_icon, type_color, title, body, duration, source.

control.proto — app → drone (request)

  • AnnotationCtrl — request to add an annotation. Fire-and-forget, like LightsCtrl.

telemetry.proto — drone → all clients (authoritative, broadcast, logged)

  • AnnotationTel — the annotation that now exists on the dive. The drone echoes a client's AnnotationCtrl here to every connected client (so clients converge), can also originate one itself (source = DRONE), and writes it to the logfile.

Design notes

  • Self-contained annotations — display fields are inline, so any client / the .bez / downstream tooling can render an annotation without a second lookup; a late joiner's GetTelemetryReq("AnnotationTel") returns something fully renderable. Captures point-in-time appearance, so renaming a type in Cloud later doesn't retro-mutate old dives.
  • type_slug for correlation — kept so Blueye Cloud links the annotation to its AnnotationType row on import (grouping, "show all Hazards"); empty for a free-form annotation.
  • Authoritative state comes up, not down — the app renders from the AnnotationTel it gets back, not from its own Ctrl, so multiple connected clients converge (client 1 adds → client 2 sees it).
  • No timestamp on Annotation — the enclosing BinlogRecord carries the time, like every other logged sample.
  • source is an informational provenance hint, not a security claim — intentionally not enforced (first-party, non-adversarial protocol); the app sets APP, the drone sets DRONE. See review thread replies.
  • Additive & backward-compatible, no new imports.

Open question for review

AnnotationTel is a discrete event, not periodic state. This telemetry plane is built around publish/log frequency (SetPubFrequencyReq / SetLogFrequencyReq, in Hz). Please confirm the bus can publish/log it on-change, once per event — i.e. every annotation is delivered to subscribers and written to the logfile, with no rate-based sampling that could merge two quick annotations or drop one.

Validation

  • protoc compiles all protos together (syntax + cross-refs resolve). ✓
  • No lines > 120 chars (protolint max_line_length). ✓
  • VersionPrefix intentionally not bumped — the protocol version tracks the BlueyeApp version and is bumped together with the app.

Not in this PR

  • App UI (command palette, FontAwesome icon rendering — the FA7 Pro lookup is already in BlueyeApp).
  • Blueye Cloud .bez parser that reconstructs annotation rows from AnnotationTel records (correlating by type_slug, falling back to the inlined display fields for free-form annotations).

🤖 Generated with Claude Code

Define the protocol for adding annotations during a dive and syncing them
across connected clients and into the dive logfile.

Data (message_formats.proto): AnnotationType (catalogue entry), Annotation (a
recorded annotation), AnnotationCatalog (a catalogue snapshot), and the
AnnotationSource enum. Mirrors the annotation model in Blueye Cloud; types are
referenced by slug.

Down, app -> drone (requests): AnnotationCtrl (control.proto) to add one;
SetAnnotationCatalogReq/Rep (req_rep.proto) to push the catalogue.

Up, drone -> all clients (broadcast + logged): AnnotationTel and
AnnotationCatalogTel (telemetry.proto). The drone echoes a client's
AnnotationCtrl as an AnnotationTel to every connected client and writes it to
the dive logfile, so clients converge and the log is self-describing; the drone
can also originate an AnnotationTel itself. Late joiners fetch the latest via
GetTelemetryReq by message name.

Additive and backward-compatible; no new imports. VersionPrefix left untouched
(protocol version tracks the BlueyeApp version and is bumped with it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@follesoe follesoe added enhancement New feature or request new message New message definition labels Jun 29, 2026
@follesoe follesoe requested a review from Copilot June 29, 2026 12:13
@follesoe follesoe self-assigned this Jun 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds new protobuf message definitions to support “in-dive annotations”: clients can request an annotation during a dive, the drone broadcasts/logs the authoritative annotation event, and the active annotation-type catalog can be pushed and logged so the logfile remains self-describing.

Changes:

  • Introduces AnnotationSource, AnnotationType, Annotation, and AnnotationCatalog data models in message_formats.proto.
  • Adds a fire-and-forget control message AnnotationCtrl (app → drone) to request recording an annotation.
  • Adds AnnotationTel and AnnotationCatalogTel telemetry messages (drone → clients) plus SetAnnotationCatalogReq/Rep (app → drone) for catalog synchronization.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
protobuf_definitions/message_formats.proto Adds core annotation data types and the AnnotationSource enum.
protobuf_definitions/control.proto Adds AnnotationCtrl for requesting in-dive annotation creation.
protobuf_definitions/telemetry.proto Adds AnnotationTel and AnnotationCatalogTel for broadcast/logged annotation events and catalog snapshots.
protobuf_definitions/req_rep.proto Adds SetAnnotationCatalogReq/Rep for pushing the active annotation-type catalog to the drone.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread protobuf_definitions/control.proto
Comment thread protobuf_definitions/telemetry.proto Outdated
Comment thread protobuf_definitions/message_formats.proto Outdated
Document, per review feedback, that the app sets source = APP and the drone sets
DRONE for its own annotations, and that CLOUD is the post-dive cloud path not
seen on the live drone telemetry path. Documentation only — source remains an
informational provenance hint, intentionally not enforced (this is a first-party,
non-adversarial protocol).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@follesoe follesoe requested a review from jp-pino June 29, 2026 13:59
Make each Annotation self-cohesive — it now carries the type's display fields
(type_name, type_icon, type_color) inline alongside type_slug — so the drone,
connected clients, and the dive logfile can render it without a separate
catalogue. The app keeps the full catalogue locally (synced from Blueye Cloud)
to drive its palette; only complete annotations go over the wire. type_slug is
kept so Blueye Cloud can correlate the annotation to its type on import.

Removes AnnotationType and AnnotationCatalog (message_formats.proto),
SetAnnotationCatalogReq/Rep (req_rep.proto), and AnnotationCatalogTel
(telemetry.proto). No catalogue push or ordering dependency; late joiners get a
fully self-renderable annotation from GetTelemetryReq("AnnotationTel").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@follesoe follesoe requested a review from Copilot June 30, 2026 08:08
@follesoe follesoe marked this pull request as ready for review June 30, 2026 08:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread protobuf_definitions/message_formats.proto Outdated
Per review: colour -> color (matches the color/type_color field names),
catalogue -> catalog, and "cloud" -> "Cloud" to match the file's "Blueye Cloud"
usage. Comments only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread protobuf_definitions/telemetry.proto
Comment thread protobuf_definitions/telemetry.proto
@follesoe follesoe merged commit 64e9ae8 into master Jun 30, 2026
4 checks passed
@follesoe follesoe deleted the jf/in-dive-annotations branch June 30, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request new message New message definition

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants